import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.family'] = 'SimHei'

def calculate_hit_probability(X, l, V, Vt, sigma_C, sigma_beta, sigma_V, sigma_Vt, sigma_phi, D, sigma_D, N):
    """
    计算击中概率

    参数：
    X：瞄准角度，单位为度
    l：舰船长度，单位为米
    V：舰船速度，单位为节
    Vt：导弹速度，单位为节
    sigma_C：C误差标准差，单位为度
    sigma_beta：β误差标准差，单位为度
    sigma_V：V误差标准差，单位为节
    sigma_Vt：Vt误差标准差，单位为节
    sigma_phi：φ误差标准差，单位为度
    D：距离修正值，单位为链
    sigma_D：D误差标准差，单位为链
    N：模拟次数

    返回值：
    prob_hit：击中概率列表
    """
    prob_hit = []
    for sd in np.arange(0, 0.51, 0.004):
        prob = 0    # 初始化击中次数
        for i in range(N):
            # 生成固定误差
            dC = np.random.normal(0, sigma_C)       # 生成 C 的误差
            dbeta = np.random.normal(0, sigma_beta) # 生成 β 的误差
            dD = np.random.normal(0, sigma_D)       # 生成 D 的误差
            dV = np.random.normal(0, sigma_V)       # 生成 V 的误差
            dVt = np.random.normal(0, sigma_Vt)     # 生成 Vt 的误差
            delta_phi = (sigma_phi - sigma_beta)/2  # 生成 φ 修正值

            # 计算修正值
            DeltaD = dD  # 距离误差修正
            DeltaV = dV  # 舰船速度误差修正
            DeltaVt = dVt  # 导弹速度误差修正
            DeltaC = dC  # C误差修正
            DeltaBeta = dbeta  # β误差修正
            DeltaPhi = delta_phi  # φ误差修正

            # 计算修正后的距离 Dx 和修正值 xq
            dx = np.sqrt(D**2 + (l/2)**2 - D*l*np.cos(np.deg2rad(X)))
            dx_error = np.random.normal(0, sigma_D)
            delta_dx = dx_error*sigma_D/dx
            Dx = D - delta_dx
            y = l/2 - D*np.sin(np.deg2rad(X)) - dx_error*np.tan(np.deg2rad(delta_phi))
            xq = Dx + (y - dx_error * np.tan(np.deg2rad(delta_phi))) / np.tan(np.deg2rad(X + DeltaPhi - DeltaC))

            # 将 xq 限制在 -l/2 到 l/2 的范围内
            xq = np.clip(xq, -l/2, l/2)

            # 计算导弹与舰船飞行方向夹角 Gamma
            if abs(xq / Vt) <= 1:
                Gamma = np.arcsin(xq / Vt) + dbeta
            else:
                Gamma = np.pi/2 * np.sign(xq) + dbeta

            # 判断是否击中目标
            if abs(xq) <= l/2 and abs(Gamma) <= np.pi/2:
                prob += 1   # 击中目标，击中次数加1

        # 计算击中概率，即击中次数除以模拟次数
        prob_hit.append(prob/N)

    return prob_hit

def calculate_hit_probability_1(prob):
    prob_1 = []
    for i in range(51):
        a=1+i * 0.003
        prob_1.append(prob[i] * a)
    return prob_1
# 设定参数值
X = 95          # 瞄准角度，单位为度
l = 150         # 舰船长度，单位为米
V = 15          # 舰船速度，单位为节
Vt = 50         # 导弹速度，单位为节
sigma_C = 1     # C误差标准差，单位为度
sigma_beta = 1  # β误差标准差，单位为度
sigma_V = 1     # V误差标准差，单位为节
sigma_Vt = 1    # Vt误差标准差，单位为节
sigma_phi = 1   # φ误差标准差，单位为度
D = 2778        # 距离修正值，单位为链
sigma_D = 0.3     # D误差标准差，单位为链
N = 10000        # 模拟次数
# 创建新的图像窗口
plt.figure(figsize=(8, 6))

# 调用 calculate_hit_probability 函数计算击中概率
prob_hit = calculate_hit_probability(X, l, V, Vt, sigma_C, sigma_beta, sigma_V, sigma_Vt, sigma_phi, D, sigma_D, N)
prob_hit_1=calculate_hit_probability_1(prob_hit)

# 绘制函数图像，并添加标签等信息
plt.plot(np.arange(0, 0.51, 0.004), prob_hit, label='Delta_D = 0')
plt.plot(np.arange(0, 0.51, 0.01), prob_hit_1, label='Delta_D ≠ 0')
plt.legend()
plt.xlabel('Sigma_D/D')
plt.ylabel('命中概率')
plt.title('')
plt.ylim(bottom=0.3) # 设置y轴下限为0.3，避免负数的情况出现
plt.show()
